
#ifndef _IPC_SHARE_MEM_H_
#define _IPC_SHARE_MEM_H_

#include <stdint.h>

/*
 *  共享内存的公共头部
 *  也就是说创建自己的共享内存结构体时,把该结构放在最前面,例如:
 *  typedef struct MyStruct {
 *      PGShareMemBase base;
 *      ...
 *  } MyStruct;
 */
typedef struct PGShareMemBase {
    uint32_t size; /* 整个共享内存大小 */
    int32_t isBusy;
    union {
        void* p;
        int32_t i;
        int32_t arr[2];
    } id; /* 兼容64位 */
#if !(defined(WIN32) || defined(WIN64) || defined(WINCE) || defined(_MSC_VER))
    uint32_t userIndex; /* 接入用户数序号,只增不减 */
    int32_t userPidList[8]; /* 记录接入用户的pid,当所有用户都下线时,删除共享内存 */
    char tagPath[128]; /* linux版需要创建和挂靠一个文件夹路径,记录该路径,释放时删除 */
#endif
} PGShareMemBase;

/* 返回共享内存指针,创建自己的共享内存结构时请把 PGShareMemBase 定义在最前面 */
void* ipcshm_create(const char* uniqueId, uint32_t memSize);
void ipcshm_release(void** base);

/* 等待空闲,正常返回0 */
void ipcshm_lock(void* base, int32_t timeoutMs = 3000);
void ipcshm_unlock(void* base);

/* 获取创建共享内存所需要的id字符串 */
void ipcshm_getuuid(char* buff, int32_t buffSize, const char* append);

#ifdef __cplusplus
/* -------------------- c++封装 -------------------- */

class CIpcShm {
public:
    CIpcShm()
    {
        mMem = NULL;
    }
    ~CIpcShm()
    {
        ShmRelease();
    }
    void ShmRelease()
    {
        if (mMem) {
            ipcshm_release(&mMem);
        }
        mMem = NULL;
    }
    void* ShmInit(int32_t size, const char* name)
    {
        if (mMem) {
            ipcshm_release(&mMem);
        }
        ipcshm_getuuid(mUUID, sizeof(mUUID), name);
        mMem = ipcshm_create(mUUID, size);
        return mMem;
    }
    const char* GetUUID() {
        return mUUID;
    }
private:
    void* mMem;
    char mUUID[128];
};

/* -------------------- c++封装 -------------------- */
#endif

#endif // _IPC_SHARE_MEM_H_
